#!/bin/bash

# 返回码
declare -i ret_ok=0                                 # 成功
declare -i ret_upgrade_failed=1                     # 升级失败 
declare -i ret_failed_dictionary_no_space=2         # 失败 文件夹空间不够
declare -i ret_failed_file_extra_error=3            # 失败 升级包解压失败
declare -i ret_failed_file_context_wrong=4          # 失败 文件内容错误
declare -i ret_failed_file_no_find_ha_work_path=5   # 失败 找不到ha工作目录
declare -i ret_failed_ha_upgrade_exec_failed=6      # 失败 ha升级脚本执行错误
declare -i ret_failed_arg_err=7                     # 失败 参数设置失败
declare -i ret_failed_upgrade_version_err=8         # 失败 升级的版本错误
declare -i ret_failed_inactive_packet_exist=9        # 失败 存在未生效的版本
declare -i ret_failed_stop_sevice_failed=10         # 失败 停止运行进程失败
declare -i ret_failed_upgrade_replace_file_err=11   # 失败 升级替换文件程序失败
declare -i ret_failed_get_file_type_err=12          # 失败 获取升级包类型失败
declare -i ret_failed_check_cms_err=13              # 失败 签名文件校验失败
declare -i ret_failed_file_not_exist_or_empty=14    # failed file not exist or empty
declare -i ret_failed_file_name_invalid=15          # failed file name extension invalid
declare -i ret_failed_versioninfo_get_failed=16     # failed get version info failed
declare -i ret_failed_write_inactive_info_failed=17 # failed write inactive info failed
declare -i ret_failed_effect_no_packet_info=18      # failed effect no packet info
declare -i ret_failed_set_upgrade_process_failed=19 # set upgrade process file failed
declare -i ret_failed_effect_restart_failed=20      # failed effect restart failed
declare -i ret_failed_run_task_exist=21             # run task file exist failed
declare -i ret_failed_file_no_find_upgrade_file=22  # failed find no upgrade file
declare -i ret_failed_copy_file_failed=23           # copy backup file failed
declare -i ret_failed_copy_crl_file_failed=24       # copy crl file failed

SCRIPT_PATH="/opt/middleware/AtlasEdge/software/edge_site/edge_manager/src/script"
WORK_PATH="/opt/middleware/AtlasEdge"

. ${SCRIPT_PATH}/log_util.sh
. ${SCRIPT_PATH}/common.sh

ATLASEDGE_CONFIG_FILE="${WORK_PATH}/config/config.ini"
ATLASEDGE_BACKUP_BIN_PATH=${WORK_PATH}/edge_backup

ProcName="edge_main.sh"
SAVE_CRL_PATH="/etc/hwsipcrl/"
SAVE_CRL_FILE_NAME="ascendsip.crl"
STATE_SAME=0
STATE_NEW=1
STATE_OLD=2

# 默认参数
file_type=""
operation="install"
installMethod="force"
enableMethod="now"

ha_work_path=""
ATLASEDGE_FILE_SUB_DIR=""
ATLASEDGE_PRE_UPGRADE_VERSION=""
ATLASEDGE_PRE_UPGRADE_PATH=${WORK_PATH}/edge_upgrade
ATLASEDGE_SPACE_NEED=409600

function usage() {
    echo "upgrade  -- upgrade software version"
    echo "parameters:"
    echo "    -i : install method force/normal default:force force: ignore version check  normal: check version deny high to low version"
    echo "    -e : enable method now/delay default:now  now: effect now delay: effect later wait effect cmd"
    echo "    -t : type  HA/AtlasEdge"
    echo "    -f : upgrade file path"
    echo "    -h : help"
    echo "usage: "
    echo "     ./upgrade -i force -f ../../AtlasEdge-1.0.0.tar.gz -e now -t AtlasEdge"
    echo "     ./upgrade -i force -f ../../HA-1.3.0.2-aarch64.tar.gz -e now -t HA"
}

# 获取升级子目录
check_upgrade_sub_dir(){
    if [ ! -f $ATLASEDGE_PRE_UPGRADE_PATH/version.xml -o ! -d $ATLASEDGE_PRE_UPGRADE_PATH/software ]; then
        logger_Warn "find no edge version.xml:"$(basename ${ATLASEDGE_PRE_UPGRADE_PATH})
        return $ret_failed_file_context_wrong
    fi

    ATLASEDGE_PRE_UPGRADE_VERSION=`grep Version "$ATLASEDGE_PRE_UPGRADE_PATH/version.xml" | awk -F ">" '{print $2}' | awk -F "<" '{print $1}'`
    if [ $ATLASEDGE_PRE_UPGRADE_VERSION == "" ];then
        logger_Warn "version info get failed upgradeV:$ATLASEDGE_PRE_UPGRADE_VERSION"
        return $ret_failed_versioninfo_get_failed
    fi

    logger_Debug "subDir: " $(basename ${ATLASEDGE_PRE_UPGRADE_PATH})

    return 0
}

function remove_edge_pre_upgrade() {
    if [ -d ${ATLASEDGE_PRE_UPGRADE_PATH} ];then
        rm -rf ${ATLASEDGE_PRE_UPGRADE_PATH}
    fi
}

function check_space_enough() {
    request_space=$1
    avail_space=$(df "$WORK_PATH" | awk 'NR==2 { print $4 }')
    if [ ${avail_space} -lt ${request_space} ]; then
        logger_Warn "$(basename ${WORK_PATH}) not enough space avalid:" ${avail_space} " need:" ${request_space}
        return ${ret_failed_dictionary_no_space}
    fi

    extracted_file_size=`tar tvf ${upgrade_file} | awk '{sum+=$3/1024} END {print sum}'`
    bigger_file_size=$[${extracted_file_size%.*}+1]
    if [ ${bigger_file_size} -ge ${ATLASEDGE_SPACE_NEED} ]; then
        logger_Warn "file size is too big ,size is ${extracted_file_size}"
        return ${ret_failed_dictionary_no_space}
    fi

    return 0
}

function precheck_env() {
    # clean edge_upgrade of last upgrade operation
    remove_edge_pre_upgrade
    # check space enough
    check_space_enough ${ATLASEDGE_SPACE_NEED}
    return $?
}

# 获取HA工作目录 同时检测安装类型是否正常
get_ha_work_path(){
    ha_work_path=$(ReadINIfile ${ATLASEDGE_CONFIG_FILE} SYS ha_work_path)
    if [ -z "$ha_work_path" ]; then
       logger_Warn "get ha work path from config file failed"
       if [ -n "$MINDX_EDGE_HA_HOME" ]; then
           logger_Info "get ha work path from env"
           ha_work_path=$MINDX_EDGE_HA_HOME
       else
           logger_Warn "get ha work path from env failed"
           ha_home_in_profile=$(cat /etc/profile | grep MINDX_EDGE_HA_HOME | awk -F '=' '{print $2}')
           if [ -n "$ha_home_in_profile" ]; then
               logger_Info "get ha work path from profile"
               ha_work_path=$ha_home_in_profile
           else
               logger_Info "get ha work path from install_dir"
               install_dir=$(ReadINIfile ${ATLASEDGE_CONFIG_FILE} SYS install_dir)
               ha_work_path="$(dirname $install_dir)/ha"
           fi
       fi
       WriteINIfile ${ATLASEDGE_CONFIG_FILE} SYS ha_work_path ${ha_work_path}
    fi

    logger_Debug "HA_PATH : $(basename ${ha_work_path}) !"

    if [ ! -d "${ha_work_path}" -o -z "${ha_work_path}" ]; then
        logger_Warn "find no ha work dir:" $(basename ${ha_work_path})
        return $ret_failed_file_no_find_ha_work_path
    fi

    return 0
}

# ha升级执行函数 后续优化 放到ha工程中
function ha_upgrade(){
    # 获取ha安装目录 检测是否满足安装要求
    get_ha_work_path
    ret=$?
    if [ ${ret} != 0 ]; then
        if [ "$operation" = "install" ]; then
            logger_Info "create ha work path"
            mkdir -p $ha_work_path
        else
            logger_Warn "check args invalid ret:" ${ret}
            return ${ret}
        fi
    fi

    local ha_upgrade_dir="$ha_work_path/ha_upgrade"
    if [ "$operation" = "install" ]; then
       ha_upgrade_script="$ha_work_path/module/hacom/script/upgrade.sh"
       if [ ! -f "$ha_upgrade_script" ]; then
           logger_Info "upgrade.sh not exists, only extract files"
           mkdir -p $ha_upgrade_dir
           tar mxzf $upgrade_file -C $ha_upgrade_dir
           ret=$?
       else
           bash $ha_upgrade_script -i $installMethod -f $upgrade_file -e $enableMethod -w $ha_work_path
           ret=$?
       fi
    elif [ "$operation" = "effect" ]; then
       if [ ! -f "${ha_work_path}/module/hacom/script/upgrade.sh" -a -f "$ha_upgrade_dir/install.sh" ]; then
           pushd $ha_upgrade_dir
           ./install.sh -p $(dirname $ha_work_path) -f
           ret=$?
           rm -rf $ha_upgrade_dir
           popd
       else
           bash ${ha_work_path}/module/hacom/script/upgrade.sh -i $installMethod -e $enableMethod -w $ha_work_path -o $operation
           ret=$?
       fi
    elif [ "$operation" = "uninstall" ];then
        bash ${ha_work_path}/module/hacom/script/upgrade.sh -w $ha_work_path -o $operation
        ret=$?
    fi

    local ha_pre_upgrade_dir="${ha_work_path}/ha_upgrade"
    if [ -d "$ha_pre_upgrade_dir" ]; then
        chown -R HwHiAiUser:HwHiAiUser $ha_pre_upgrade_dir
        logger_Info "change $ha_pre_upgrade_dir owner and group to HwHiAiUser"
    fi

    if [ "$ret" != "0" ]; then
        logger_Warn "ha upgrade:${operation} failed"
        return ${ret_failed_ha_upgrade_exec_failed};
    fi

    return 0
}

function stop_service(){
    bash ${SCRIPT_PATH}/stop.sh stopapp
    ret=$?
    if [ ${ret} != 0 ];then
        logger_Warn "stop service failed ret:" ${ret}
        return $ret_failed_stop_sevice_failed
    fi

    logger_Debug "edge stop service OK"
    return 0
}

function start_service(){
    bash ${SCRIPT_PATH}/start.sh
    ret=$?
    if [ ${ret} != 0 ];then
        logger_Warn "start service failed ret:" ${ret}
        return $ret_failed_start_sevice_failed
    fi
    logger_Debug "edge start service OK"
    return 0
}

function restart_service(){
    bash ${SCRIPT_PATH}/start.sh restart
    ret=$?
    if [ ${ret} != 0 ];then
        logger_Warn "restart service failed ret:" ${ret}
        return $ret_failed_start_sevice_failed
    fi
    logger_Debug "edge restart service OK"
    return 0
}

# 执行升级动作 拷贝新程序到制定目录
function upgrade_proc(){
    ${WORK_PATH}/edge_main.sh upgrade
    ret=$?
    if [ ${ret} != 0 ];then
        logger_Warn "upgrade replace file failed ret:" ${ret}
        return $ret_failed_upgrade_replace_file_err
    fi

    return 0
}

check_args_valid(){

    if [ -z $file_type ]; then
        logger_Warn "upgrade file type not assign"
        return ${ret_failed_arg_err}
    fi

    # effect and uninstall opeartion no need check as follow so ret
    if [ $operation = "effect" -o $operation = "uninstall" ]; then
        return 0
    fi

    if [[ ! -f $upgrade_file || ! -f $sign_file || ! -f $crl_file ]]; then
        logger_Warn "input fileDir is empty or not exist upgradefile:[$(basename $upgrade_file)] signfile:[$(basename $sign_file)] crlfile:[$(basename $crl_file)]"
        return ${ret_failed_file_not_exist_or_empty}
    fi

    if [[ $upgrade_file != *.tar.gz  || $sign_file != *.cms || $crl_file != *.crl ]];then
        logger_Warn "input fileDir name extension is invalid upgradefile:[$(basename $upgrade_file)] signfile:[$(basename $sign_file)] crlfile:[$(basename $crl_file)]"
        return ${ret_failed_file_name_invalid}
    fi

    return 0
}
function verify_package()
{
    verify_crl=${crl_file}
    # 标记是否更新本地crl文件，默认为true，只有当本地文件更新或者相同的时候才不更新
    update_local_crl_flag="true"
    if [[ -f ${SAVE_CRL_PATH}/${SAVE_CRL_FILE_NAME} ]]; then
        # 如果本地存在crl文件，先校验本地的crl是否合法
        local_crl_file=${SAVE_CRL_PATH}/${SAVE_CRL_FILE_NAME}
        verify_crl_file ${local_crl_file}
        ret=$?
        if [[ ${ret} != ${ret_ok} ]]; then
            # 如果本地文件校验失败，则直接用包中crl文件做校验
            logger_Info "The local crl file self verify failed, use software package crl file to verify and update local crl file"
            update_local_crl_flag="true"
        else
            logger_Info "The local crl file self verify success, and now compared with the software package crl, which is more newer?"
            # 本地crl校验成功，则需要比较待升级的crl与本地的crl谁更新，始终使用最新的crl
            compare_two_crl_file ${crl_file} ${local_crl_file}
            ret=$?
            case ${ret} in
                ${STATE_SAME})
                    logger_Info "The software package crl file the same to the local crl file, use software package crl file to verify and no need update local crl file"
                    update_local_crl_flag="false"
                    ;;
                ${STATE_NEW})
                    logger_Info "The software package crl file is newer than the local crl file, use software package crl file to verify and update local crl file"
                    update_local_crl_flag="true"
                    ;;
                ${STATE_OLD})
                    verify_crl=${local_crl_file}
                    update_local_crl_flag="false"
                    logger_Info "The software package crl file is older than the local crl file, use the local crl file to verify and no need update local crl file"
                    ;;
                *)
                    update_local_crl_flag="false"
                    logger_Warn "Compare local crl file and the software package crl file failed: ret code ${ret}, use software package crl file to verify"
                    ;;
            esac
        fi
    fi

    # 校验crl和cms和软件包是否配套合法
    ${WORK_PATH}/software/libs/ld-linux-aarch64.so.1 --library-path ${WORK_PATH}/software/libs/ ${WORK_PATH}/software/bin/verify_tool ${verify_crl} ${sign_file} ${upgrade_file}
    ret=$?
    if [[ ${ret} != 0 ]]; then
        logger_Warn "check cms failed ret:" ${ret}
        return ${ret_failed_check_cms_err}
    fi

    if [[ "$update_local_crl_flag" == "true" ]]; then
        logger_Info "Start to update the local crl file"
        update_local_crl_file ${crl_file}
        ret=$?
        if [[ ${ret} != ${ret_ok} ]]; then
            logger_Warn "Update the local crl file failed"
        else
            logger_Info "Update the local crl file success"
        fi
    fi
    return ${ret_ok}
}

function verify_crl_file()
{
    local need_verify_crl_file=$1
    compare_two_crl_file ${need_verify_crl_file} ${need_verify_crl_file}
    ret=$?
    if [[ ${ret} == ${STATE_SAME} ]]; then
        return ${ret_ok}
    fi
    return 1
}

function compare_two_crl_file()
{
    local new_crl_file=$1
    local old_crl_file=$2
    # 需要比较待升级的crl与本地的crl谁更新，始终使用最新的crl
    ${WORK_PATH}/software/libs/ld-linux-aarch64.so.1 --library-path ${WORK_PATH}/software/libs/ ${WORK_PATH}/software/bin/verify_tool ${new_crl_file} ${old_crl_file}
    ret=$?
    logger_Info "Compare crl ($(basename ${new_crl_file})) with ($(basename ${old_crl_file})) result: ${ret} (0=STATE_SAME  1=STATE_NEW  2=STATE_OLD,  others is error code)"
    return ${ret}
}

function update_local_crl_file()
{
    update_crl_file=$1
    if [[ ! -d ${SAVE_CRL_PATH} ]]; then
        mkdir -p ${SAVE_CRL_PATH}
    fi
    chown root:root ${SAVE_CRL_PATH}
    chmod 755 ${SAVE_CRL_PATH}
    # 保存新的crl文件，到固定目录下
    cp -f ${update_crl_file} ${SAVE_CRL_PATH}/${SAVE_CRL_FILE_NAME}
    cp_ret=$?
    if [[ ${cp_ret} != 0 ]]; then
        logger_Warn "Copy the crl file ($(basename ${update_crl_file})) failed, ret: ${cp_ret}"
        return ${ret_failed_copy_crl_file_failed}
    fi
    chown root:root ${SAVE_CRL_PATH}/${SAVE_CRL_FILE_NAME}
    chmod 644 ${SAVE_CRL_PATH}/${SAVE_CRL_FILE_NAME}
    return ${ret_ok}
}

check_package_cms() {

    # effect and uninstall operation no need check as follow so ret
    if [[ ${operation} = "effect" || ${operation} = "uninstall" ]]; then
        return 0
    fi
    verify_package
    ret=$?
    if [[ ${ret} != 0 ]]; then
        logger_Warn "check cms failed ret:" ${ret}
        return ${ret_failed_check_cms_err}
    fi
    return 0
}

check_package_inner_file_name(){
    check_file_name=`tar tvf ${upgrade_file} | awk '{print $6}'`
    if [[ ${check_file_name} =~ "../" || ${check_file_name} =~ "..\\" || ${check_file_name} =~ ".\\" || ${check_file_name} =~ "./" || ${check_file_name} =~ "~/" ]]; then
        logger_Warn "file name is Invalid"
        return ${ret_failed_file_context_wrong}
    fi
}

# 非强制模式下不允许版本回退,检测版本号是否新的
check_version_is_new(){
    now_version=`grep Version "$WORK_PATH/version.xml" | awk -F ">" '{print $2}' | awk -F "<" '{print $1}'`

    if [  $ATLASEDGE_PRE_UPGRADE_VERSION == "" -o $now_version == "" ];then
        logger_Warn "version info get failed nowV:$now_version upgradeV:$upgrade_version"
        return $ret_failed_file_context_wrong
    fi

    logger_Info "pgreade version $ATLASEDGE_PRE_UPGRADE_VERSION now: $now_version"

    version_compare $ATLASEDGE_PRE_UPGRADE_VERSION $now_version
    case $? in
        0)op='=';;
        1) op='>';;
        2) op='<';;
    esac
    
    if [ "$op" = "<" ];then
        logger_Warn "upgreade version little return $ATLASEDGE_PRE_UPGRADE_VERSION now: $now_version"
        return $ret_failed_upgrade_version_err
    fi

    return 0
}

# 删除待升级目录
delete_pre_upgrade_dir(){
    if [ "$1" != "" -a -d "$1" ];then
        logger_Info "del upgrade dir:[$(basename $1)]"
        rm -rf $1
    else
        logger_Info "null del upgrade dir:[$(basename $1)]"
    fi
}

write_effect_flag_to_config(){
    if [ ! -d $ATLASEDGE_PRE_UPGRADE_PATH ]; then
        logger_Warn "find no upgrade dir $(basename $ATLASEDGE_PRE_UPGRADE_PATH) failed"
        return $ret_failed_file_no_find_upgrade_file
    fi

    touch $ATLASEDGE_PRE_UPGRADE_PATH/effect_flag
}

set_upgrade_flag()
{
    echo $$ > ${WORK_PATH}/upgrade.pid
}

clear_upgrade_flag()
{
    if [ -f ${WORK_PATH}/upgrade.pid ];then
        rm ${WORK_PATH}/upgrade.pid
    fi

    if [ -f ${WORK_PATH}/upgrade.result ];then
        rm ${WORK_PATH}/upgrade.result
    fi
}

function backup_prev_crl_files()
{
    cp -f $(get_cert_dir)/FDCrl* ${ATLASEDGE_PRE_UPGRADE_PATH}/software/edge_core/certFD/ > /dev/null 2>&1
    local ret=$?
    logger_Info "backup prev crl file: ret $ret"
}

function update_config_file()
{
    local target_file=${WORK_PATH}/software/edge_core/conf/edgecore.yaml
    local old_port=$(grep -Po 'mqttServerInternal.*:\K[0-9]+' $target_file)
    local new_port=$(grep -Po 'mqttServerInternal.*:\K[0-9]+' ${ATLASEDGE_PRE_UPGRADE_PATH}/software/edge_core/conf/edgecore.yaml)
    logger_Info "old_port=$old_port, new_port=$new_port"

    if [ "$old_port" -ne "$new_port" ]; then
        logger_Info "update mqttServerInternal port number"
        sed -i "/mqttServerInternal/{s/$old_port/$new_port/;}" $target_file
        local backup_base_dir=$WORK_PATH/config/backup
        local backup_file=${backup_base_dir}/$(basename ${target_file})
        local mod_check_file="/run/atlasedge_mod_check"
        sha256sum $target_file > ${mod_check_file}.checksum
        dd if=${mod_check_file}.checksum of=${backup_file}.checksum conv=fsync status=none
        dd if=$target_file of=${backup_file} conv=fsync status=none
        logger_Info "upgrade verify and backup for $(basename ${target_file})"
    fi
}

function backup_and_copy_upgrade_glibc()
{
    if [ -f "${ATLASEDGE_PRE_UPGRADE_PATH}/software/libs/libm-2.29.so" ]; then
        logger_Info "libm-2.29.so already exists"
        return
    fi

    logger_Info "make lib links"
    pushd ${ATLASEDGE_PRE_UPGRADE_PATH}/software/libs/
    ln -sf libm-2.30.so libm-2.29.so
    ln -sf libdl-2.30.so libdl-2.29.so
    ln -sf libpthread-2.30.so libpthread-2.29.so
    ln -sf ld-2.30.so ld-2.29.so
    ln -sf libc-2.30.so libc-2.29.so
    popd
}

backup_and_copy_upgrade_file()
{
    # backup file
    if [ -d ${ATLASEDGE_BACKUP_BIN_PATH} ]; then
        rm -rf ${ATLASEDGE_BACKUP_BIN_PATH}/software
    else
        mkdir -p $ATLASEDGE_BACKUP_BIN_PATH
    fi
    cp -af ${WORK_PATH}/edge_upd_effect.sh ${ATLASEDGE_BACKUP_BIN_PATH}/
    cp -arf ${WORK_PATH}/software ${WORK_PATH}/edge_main.sh ${WORK_PATH}/run.sh ${WORK_PATH}/version.xml ${ATLASEDGE_BACKUP_BIN_PATH}/
    if [ $? -ne 0 ]; then
        logger_Warn "move file failed"
        return ${ret_failed_copy_file_failed}
    fi

    mv -f ${WORK_PATH}/edge_main.sh ${WORK_PATH}/edge_main.sh.back
    mv -f ${WORK_PATH}/edge_upd_effect.sh ${WORK_PATH}/edge_upd_effect.sh.back
    cp -af $ATLASEDGE_PRE_UPGRADE_PATH/software/edge_site/edge_manager/src/script/edge_main.sh ${WORK_PATH}/edge_main.sh
    cp -af $ATLASEDGE_PRE_UPGRADE_PATH/software/edge_site/edge_manager/src/script/edge_upd_effect.sh ${WORK_PATH}/edge_upd_effect.sh
    cp -af $ATLASEDGE_PRE_UPGRADE_PATH/software/edge_site/edge_manager/config/atlasedge.service ${WORK_PATH}/software/edge_site/edge_manager/config/
    sed -i "s|"{"work_path"}"|${WORK_PATH}|g" ${WORK_PATH}/software/edge_site/edge_manager/config/atlasedge.service
    backup_and_copy_upgrade_glibc
}

# exit func
function exit_trap()
{
    trap - INT TERM EXIT QUIT ABRT
    logger_Info "upgrade exit pid: $$"
}

function main()
{
    trap exit_trap INT TERM EXIT QUIT ABRT
    logger_Info "upgrade begin pid: $$"

    while getopts "f:s:c:i:e:t:o:h" arg
    do
        case $arg in
            o)
                if [ "$OPTARG" == "install" -o "$OPTARG" == "uninstall" -o "$OPTARG" == "effect" ]; then
                    operation=$OPTARG
                    logger_Debug "operation's arg:$operation"
                else
                    logger_Warn "operation err install uninstall effect in:" $OPTARG
                    return ${ret_failed_arg_err};
                fi
                ;;
            i)
                if [ "$OPTARG" == "force" -o "$OPTARG" == "normal" ]; then
                    installMethod=$OPTARG
                    logger_Debug "installMethod's arg:$installMethod"
                else
                    logger_Warn "installMethod err force normal in:" $OPTARG
                    return ${ret_failed_arg_err};
                fi
                ;;
            f)
                upgrade_file=$(readlink -f $OPTARG)
                logger_Debug "upgradefile's arg:$upgrade_file"
                ;;
            s)
                sign_file=$(readlink -f $OPTARG)
                logger_Debug "signfile's arg:$sign_file"
                ;;
            c)
                crl_file=$(readlink -f $OPTARG)
                logger_Debug "crlfile's arg:$crl_file"
                ;;
            e)
                if [ "$OPTARG" == "now" -o "$OPTARG" == "delay" ]; then
                    enableMethod=$OPTARG
                    logger_Debug "enableMethod's arg:$enableMethod"
                else
                    logger_Warn "enableMethod err now delay in:" $OPTARG
                    return ${ret_failed_arg_err};
                fi
                ;;
            t)
                if [ "$OPTARG" == "AtlasEdge" -o "$OPTARG" == "HA" ]; then
                    file_type=$OPTARG
                    logger_Debug "file_type's arg:$file_type"
                else
                    logger_Warn "fileType err AtlasEdge HA in:" $OPTARG
                    return ${ret_failed_arg_err};
                fi
                ;;
            h)
                usage
                exit 1
                ;;
            ?)  
                logger_Warn "unkown argument:" $OPTARG "args:$@"
                exit 1
            ;;
        esac
    done

    # 检测参数是否合理
    check_args_valid
    ret=$?
    if [ ${ret} != 0 ];then
        logger_Warn "check args invalid ret:" ${ret}
        logger_Warn "invalid cmd params: ${*}"
        return ${ret}
    fi

    # 检测签名文件是否符合要求
    check_package_cms
    ret=$?
    if [ ${ret} != 0 ];then
        logger_Warn "check package cms:" ${ret}
        return ${ret}
    fi

    # ha安装单独进行，后续优化 调用ha工作目录脚本进行升级
    if [ "$file_type" = "HA" ]; then
        ha_upgrade
        ret=$?
        return $ret
    fi

    if [ $operation = "effect" ]; then

        write_effect_flag_to_config  $file_type
        ret=$?
        if [ ${ret} != 0 ];then
            logger_Warn "effect error ret:" ${ret}
            return ${ret}
        fi
        backup_and_copy_upgrade_file
        logger_Info "effect $file_type begin restart app"
        restart_service
        ret=$?
        if [ ${ret} != 0 ];then
            logger_Warn "effect error systemctl failed ret:" ${ret}
            return ${ret_failed_effect_restart_failed}
        fi
        return 0
    elif [ $operation = "uninstall" ];then
        logger_Warn "not support uninstall operation"
        return 0
    fi

    precheck_env
    ret=$?
    if [ ${ret} != 0 ];then
        logger_Warn "pre check env failed, ret:${ret}"
        return ${ret}
    fi

    logger_Info "fileType:" $file_type " installMethond: "  $installMethod " enableMethod:"  $enableMethod  "upgradeFile:" $(basename $upgrade_file)

    check_package_inner_file_name
    ret=$?
    if [ ${ret} != 0 ]; then
        logger_Warn "file package inner file name is Invalid"
        return ${ret}
    fi

    mkdir -p ${ATLASEDGE_PRE_UPGRADE_PATH}/
    rm -rf ${ATLASEDGE_PRE_UPGRADE_PATH}/*

    #解压程序到待升级区
    tar mxzf ${upgrade_file} -C ${ATLASEDGE_PRE_UPGRADE_PATH}
    if [ "$?" != "0" ]; then
        logger_Warn "tar file  failed"
        delete_pre_upgrade_dir $ATLASEDGE_PRE_UPGRADE_PATH
        return ${ret_failed_file_extra_error};
    fi
    update_config_file
    backup_and_copy_upgrade_glibc

    chown -R HwHiAiUser:HwHiAiUser ${ATLASEDGE_PRE_UPGRADE_PATH}
    chmod -R a+w $WORK_PATH

    # 检测升级子目录 如果失败，文件包错误
    check_upgrade_sub_dir
    ret=$?
    if [ ${ret} != 0 ];then
        logger_Warn "check upgrade sub dir failed"  ${ret}
        delete_pre_upgrade_dir ${ATLASEDGE_PRE_UPGRADE_PATH}
        return ${ret}
    fi

    backup_prev_crl_files

    # normal模式 非强制 不允许新版本升级到老版本
    if [ "$installMethod" = "normal" ]; then
        check_version_is_new
        ret=$?
        if [ ${ret} != 0 ];then
            logger_Warn "check version failed"  ${ret}
            delete_pre_upgrade_dir ${ATLASEDGE_PRE_UPGRADE_PATH}
            return ${ret}
        fi
    fi

    # 延迟生效 立即返回 等待主进程重新启动后执行升级后半段操作
    if [ "$enableMethod" = "delay" ]; then
        logger_Info "edge upgrade delay enableMethod wait effect cmd now exit"
        return $ret_ok
    else
        write_effect_flag_to_config $file_type
        ret=$?
        if [ ${ret} != 0 ];then
            logger_Warn "effect package failed" ${ret}
            delete_pre_upgrade_dir ${ATLASEDGE_PRE_UPGRADE_PATH}
        fi
    fi

    # set upgrade flag
    set_upgrade_flag
    set_upgrade_progress $WORK_PATH $UPGRADE_BEGIN
    ret=$?
    if [ ${ret} != 0 ];then
        logger_Warn "set upgrade process failed"  ${ret}
        return ${ret_failed_set_upgrade_process_failed}
    fi

    backup_and_copy_upgrade_file

    # 检查是否进程存在
    IsRunning="`ps -ww -eo pid,cmd | grep -v grep | grep -w ${ProcName}`"
    if [ ! -z "${IsRunning}" ]; then
        #强制模式 先停止进程服务
        stop_service
        ret=$?
        if [ ${ret} != 0 ];then
            logger_Warn "stop service failed "  ${ret}
            delete_pre_upgrade_dir ${ATLASEDGE_PRE_UPGRADE_PATH}
            clear_upgrade_flag
            return ${ret}
        fi
        logger_Info "stop service"
    fi

    # 替换文件操作
    upgrade_proc
    ret=$?
    if [ ${ret} != 0 ];then
        logger_Warn "upgrade proc failed "  ${ret}
        delete_pre_upgrade_dir ${ATLASEDGE_PRE_UPGRADE_PATH}
    fi

    # 原来程序运行，升级后还是拉起来
    if [ ! -z "${IsRunning}" ]; then
        start_service
        logger_Info "start service"
    fi

    delete_pre_upgrade_dir ${ATLASEDGE_PRE_UPGRADE_PATH}
    clear_upgrade_flag
    set_upgrade_progress $WORK_PATH $UPGRADE_DONE
    logger_Info "atlasEdge upgrade OK"
    return $ret
}

main "$@"
RESULT=$?
exit $RESULT